package org.dromara.quick.chat.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.lock.annotation.Lock4j;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.exception.base.BaseException;
import org.dromara.common.core.utils.IdGenerator;
import org.dromara.common.model.enums.channel.ChannelBlacklistStatusEnum;
import org.dromara.common.model.enums.channel.ChannelTypeEnum;
import org.dromara.common.model.enums.im.*;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.constant.CacheConstants;
import org.dromara.quick.chat.domain.ImBlacklist;
import org.dromara.quick.chat.domain.ImFriends;
import org.dromara.quick.chat.domain.ImSocialAlbum;
import org.dromara.quick.chat.mapper.ImFriendsMapper;
import org.dromara.quick.chat.model.bo.query.ImFriendsBo;
import org.dromara.quick.chat.model.bo.query.SettingsFriendsBo;
import org.dromara.quick.chat.model.statics.FriendsGroupStatics;
import org.dromara.quick.chat.model.vo.*;
import org.dromara.quick.chat.service.*;
import org.dromara.resource.api.RemoteFileService;
import org.dromara.system.api.RemoteUserService;
import org.dromara.system.api.domain.vo.RemoteUserBasicVO;
import org.dromara.utils.HanyuPinyinUtil;
import org.dromara.utils.RandomPasswordGenerator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author Stars
* @description 针对表【im_friends(好友表（通讯录），记录用户之间的好友关系及相关设置)】的数据库操作Service实现
* @createDate 2025-03-04 22:33:21
*/
@RequiredArgsConstructor
@Service
public class ImFriendsServiceImpl extends ServiceImpl<ImFriendsMapper, ImFriends>
    implements ImFriendsService{

    private final ImFriendsMapper imFriendsMapper;
    private final UserIpLocationService userIpLocationService;
    private final RemoteFileService remoteFileService;
    private final ImSocialPostService imSocialPostService;
    private final ImSocialAlbumService imSocialAlbumService;
    private final ImSocialPrivacySettingService imSocialPrivacySettingService;
    private final Converter converter;
    private final ImChannelUserService imChannelUserService;
    private final ImBlacklistService imBlacklistService;

    @DubboReference
    private RemoteUserService remoteUserService;

    @Override
    public List<ImFriendsVO> selectFriendsList(ImFriendsBo imFriendsBo, PageQuery pageQuery) {
        Long userId = LoginHelper.getUserId();
        LambdaQueryWrapper<ImFriends> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ImFriends::getSenderId, userId).orderByDesc(ImFriends::getFriendNamePinyin);
        List<ImFriendsVO> friendsList = imFriendsMapper.selectVoPage(pageQuery.build(), lambdaQueryWrapper,ImFriendsVO.class).getRecords();
        if (CollectionUtils.isEmpty(friendsList)) {
            return friendsList;
        }

        List<Long> userIds = friendsList.stream().map(ImFriendsVO::getReceiverId).distinct().collect(Collectors.toList());
        List<RemoteUserBasicVO> remoteUserBasicVOS = remoteUserService.selectListUserBasicByIds(userIds);

        // 步骤 1: 将 remoteUserBasicVOS 集合转换为一个 Map，键为 userId，值为 avatar
        Map<Long, String> userIdToAvatarMap = remoteUserBasicVOS.stream().filter(f-> StringUtils.isNoneEmpty(f.getAvatar()))
            .collect(Collectors.toMap(RemoteUserBasicVO::getUserId, RemoteUserBasicVO::getAvatar));

        // 步骤 2: 遍历 friendsList 集合，根据 receiverId 从 Map 中查找对应的 avatar 并赋值给 groupAvatar
        for (ImFriendsVO friends : friendsList) {
            if (userIdToAvatarMap.containsKey(friends.getReceiverId())) {
                friends.setAvatar(userIdToAvatarMap.get(friends.getReceiverId()));
            }
        }
        return friendsList;
    }

    @Override
    public FriendsGroupStatics selectFriendsCount() {
        Long userId = LoginHelper.getUserId();
        LambdaQueryWrapper<ImFriends> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ImFriends::getSenderId, userId).orderByDesc(ImFriends::getFriendNamePinyin);
        return imFriendsMapper.selectFriendsCount(lambdaQueryWrapper);
    }

    @Override
    public FriendsDetailVO selectFriendsDetail(ImFriendsBo imFriendsBo) {
        Long userId = LoginHelper.getUserId();
        imFriendsBo.setSenderId(userId);
        // 查询用户是否在黑名单里面
        ImBlacklist imBlacklist = imBlacklistService.getOne(new LambdaQueryWrapper<ImBlacklist>().eq(ImBlacklist::getSenderId, userId).eq(ImBlacklist::getReceiverId, imFriendsBo.getReceiverId()));

        FriendsDetailVO friendsDetail = imFriendsMapper.selectFriendsDetail(imFriendsBo);
        if (friendsDetail == null) {
            friendsDetail = new FriendsDetailVO();
            friendsDetail.setSenderId(imFriendsBo.getSenderId());
            friendsDetail.setReceiverId(imFriendsBo.getReceiverId());
            friendsDetail.setCategory(CategoryEnum.TEMPORARY.getCode());
            friendsDetail.setBurnAfterRead(BurnAfterReadEnum.NOT_ENABLED.getCode());
            friendsDetail.setBurnAfterReadDuration(0);
            friendsDetail.setChatRecordDelete(ChatRecordDeleteEnum.NOT_ENABLED.getCode());
            friendsDetail.setScreenshotProhibited(ScreenshotProhibitedEnum.NOT_ENABLED.getCode());
            // 需要查询对方的用户信息
            RemoteUserBasicVO remoteUserBasicVO = remoteUserService.selectUserBasicById(imFriendsBo.getReceiverId());
            if (remoteUserBasicVO == null) {
                throw new BaseException("用户不存在");
            }
            friendsDetail.setNickName(remoteUserBasicVO.getNickName());
            friendsDetail.setFriendNote(remoteUserBasicVO.getNickName());
            friendsDetail.setAvatar(remoteUserBasicVO.getAvatar());
        }
        if (imBlacklist == null) {
            friendsDetail.setHealthStatus(HealthStatusEnum.NORMAL.getCode());
        } else {
            friendsDetail.setHealthStatus(imBlacklist.getIsBlacklist());
        }
        RemoteUserBasicVO remoteUserBasicVO = remoteUserService.selectUserBasicById(friendsDetail.getReceiverId());
        friendsDetail.setSignature(remoteUserBasicVO.getSignature());
        friendsDetail.setAvatar(remoteUserBasicVO.getAvatar());
        friendsDetail.setNickName(remoteUserBasicVO.getNickName());
        // 查询用户删除策略
        ImSocialPrivacySettingVO imSocialPrivacySettingVO = imSocialPrivacySettingService.selectPrivacySetting(userId);
        if (imSocialPrivacySettingVO != null) {
            friendsDetail.setChatRecordDeleteStrategy(imSocialPrivacySettingVO.getChatRecordDeleteStrategy());
        }
        // 查询IP
        String ipLocation = userIpLocationService.selectUserIpLocationByUserId(imFriendsBo.getReceiverId());
        friendsDetail.setIpLocation(ipLocation);
        return friendsDetail;
    }

    @Override
    public ImFriendsChatVO selectFriendsChat(Long receiverId) {
        Long userId = LoginHelper.getUserId();
        ImFriendsChatVO cacheObject = RedisUtils.getCacheObject(CacheConstants.CACHE_IM_FRIENDS_CHAT_KEY + userId + receiverId);
        if (cacheObject != null) {
            return cacheObject;
        }
        // 查询用户是否在黑名单里面
        ImBlacklist imBlacklist = imBlacklistService.getOne(new LambdaQueryWrapper<ImBlacklist>().eq(ImBlacklist::getSenderId, userId).eq(ImBlacklist::getReceiverId, receiverId));


        // 自己
        ImFriendsChatVO imFriendsChatMy = imFriendsMapper.selectVoOne(new LambdaQueryWrapper<ImFriends>().eq(ImFriends::getSenderId, userId).eq(ImFriends::getReceiverId, receiverId), ImFriendsChatVO.class);
        if (imFriendsChatMy == null) {

            imFriendsChatMy = new ImFriendsChatVO();
            imFriendsChatMy.setSenderId(userId);
            imFriendsChatMy.setReceiverId(receiverId);

            imFriendsChatMy.setCategory(CategoryEnum.TEMPORARY.getCode());
            imFriendsChatMy.setBurnAfterRead(BurnAfterReadEnum.NOT_ENABLED.getCode());
            imFriendsChatMy.setBurnAfterReadDuration(0);
            imFriendsChatMy.setChatRecordDelete(ChatRecordDeleteEnum.NOT_ENABLED.getCode());
            imFriendsChatMy.setScreenshotProhibited(ScreenshotProhibitedEnum.NOT_ENABLED.getCode());
            // 不是好友
            imFriendsChatMy.setIsFriend(false);
            // 需要查询对方的用户信息
            RemoteUserBasicVO remoteUserBasicVO = remoteUserService.selectUserBasicById(receiverId);
            if (remoteUserBasicVO == null){
                throw new BaseException("用户不存在");
            }
            imFriendsChatMy.setFriendNote(remoteUserBasicVO.getNickName());
        }else{
            // 是好友
            imFriendsChatMy.setIsFriend(true);
        }
        if (imBlacklist == null) {
            imFriendsChatMy.setHealthStatus(HealthStatusEnum.NORMAL.getCode());
        }else{
            imFriendsChatMy.setHealthStatus(imBlacklist.getIsBlacklist());
        }

        // 对方
        ImFriendsChatVO imFriendsChatOther = imFriendsMapper.selectVoOne(new LambdaQueryWrapper<ImFriends>().eq(ImFriends::getSenderId, receiverId).eq(ImFriends::getReceiverId, userId), ImFriendsChatVO.class);
        if (imFriendsChatOther != null) {
            imFriendsChatMy.setScreenshotProhibited(imFriendsChatOther.getScreenshotProhibited());
        }

        RedisUtils.setCacheObject(CacheConstants.CACHE_IM_FRIENDS_CHAT_KEY + userId  + receiverId, imFriendsChatMy, Duration.ofHours(3));
        return imFriendsChatMy;
    }

    @Override
    public void settingsFriends(SettingsFriendsBo settingsFriendsBo) {
        Long userId = LoginHelper.getUserId();
        ImFriends friends = imFriendsMapper.selectOne(new LambdaQueryWrapper<ImFriends>().eq(ImFriends::getSenderId, userId).eq(ImFriends::getReceiverId,settingsFriendsBo.getReceiverId()));
        if (friends == null){
            throw new ServiceException("好友不存在");
        }
        ImFriends imFriends = new ImFriends();
        imFriends.setId(friends.getId());
        imFriends.setBurnAfterRead(settingsFriendsBo.getBurnAfterRead());
        imFriends.setBurnAfterReadDuration(settingsFriendsBo.getBurnAfterReadDuration());
        imFriends.setChatRecordDelete(settingsFriendsBo.getChatRecordDelete());
        imFriends.setChatRecordConfidential(settingsFriendsBo.getChatRecordConfidential());
        imFriends.setScreenshotProhibited(settingsFriendsBo.getScreenshotProhibited());
        imFriends.setFriendNote(settingsFriendsBo.getFriendNote());
        imFriendsMapper.updateById(imFriends);
        this.clearCache(friends.getSenderId() ,friends.getReceiverId());
    }

    @Transactional
    @Override
    public void removeBlackAddBlacklistFriends(Long receiverId) throws IOException {
        Long userId = LoginHelper.getUserId();
        // 更改用户为黑名单状态 healthStatus
        LambdaQueryWrapper<ImFriends> lambdaQueryWrapper = new LambdaQueryWrapper<ImFriends>().eq(ImFriends::getSenderId, userId).eq(ImFriends::getReceiverId, receiverId);
        ImFriends friends = imFriendsMapper.selectOne(lambdaQueryWrapper);
        if (friends == null) {
            throw new BaseException("好友不存在");
        }
        ImFriends imFriends = new ImFriends();
        imFriends.setId(friends.getId());

        // 设置黑名单表
        ImBlacklist imBlacklist = new ImBlacklist();
        imBlacklist.setId(IdGenerator.getId());
        imBlacklist.setSenderId(userId);
        imBlacklist.setReceiverId(receiverId);
        imBlacklist.setLastUpdateTime(new Date());
        if (friends.getHealthStatus() == ChannelBlacklistStatusEnum.NOT_IN_BLACKLIST.getCode()) {
            imFriends.setHealthStatus(ChannelBlacklistStatusEnum.IN_BLACKLIST.getCode());
            imFriendsMapper.updateById(imFriends);
            // 设置wukongIM中加入黑名单
            imChannelUserService.addToBlacklist(receiverId.toString(), userId.toString(), ChannelTypeEnum.PERSONAL_CHANNEL);
            imBlacklist.setIsBlacklist(ChannelBlacklistStatusEnum.IN_BLACKLIST.getCode());
            imBlacklistService.insertOrUpdateBlacklist(imBlacklist);
            return;
        }
        imBlacklist.setIsBlacklist(ChannelBlacklistStatusEnum.NOT_IN_BLACKLIST.getCode());
        imFriends.setHealthStatus(ChannelBlacklistStatusEnum.NOT_IN_BLACKLIST.getCode());
        imFriendsMapper.updateById(imFriends);
        // 设置wukongIM中移除黑名单
        imChannelUserService.removeFromBlacklist(receiverId.toString(), userId.toString(), ChannelTypeEnum.PERSONAL_CHANNEL);
    }


    @Override
    public void deleteFriends(Long receiverId) {
        Long userId = LoginHelper.getUserId();
        baseMapper.delete(new LambdaQueryWrapper<ImFriends>().eq(ImFriends::getSenderId,userId).eq(ImFriends::getReceiverId,receiverId));
        RedisUtils.deleteObject(CacheConstants.CACHE_IM_FRIENDS_CHAT_KEY + userId + receiverId);
    }

    @Lock4j(keys = {"#friendsId + '_' + #userId"})
    @DSTransactional(rollbackFor = ServiceException.class)
    @Override
    public void agreeAddFriend(Long userId,Long friendsId) {
        // 发送者不能等于接受者，例如：用户给对方发送要求，他自己又点击了同意，这种就是两者相同的，所以直接作废即可 。
        if (userId.equals(friendsId)) {
            return;
        }
        if(this.checkFriend(friendsId,userId)){
            throw new ServiceException("用户已存在通讯录");
        }
        // 查询用户编号，用作用户删除好友的时长
        ImSocialPrivacySettingVO imSocialPrivacySettingVO = imSocialPrivacySettingService.selectPrivacySetting(userId);
        ImSocialPrivacySettingVO imSocialPrivacySettingFriends = imSocialPrivacySettingService.selectPrivacySetting(friendsId);
        List<RemoteUserBasicVO> remoteUserBasicVOS = remoteUserService.selectListUserBasicByIds(List.of(friendsId, userId));
        Map<Long, RemoteUserBasicVO> resultMap = new HashMap<>();
        for (RemoteUserBasicVO user : remoteUserBasicVOS) {
            resultMap.put(user.getUserId(), user);
        }
        // 需要添加 2 条会话，发送方，接收方
        List<ImFriends> imFriendsList = new ArrayList<>();
        Date date = new Date();
        ImFriends imFriends = new ImFriends();
        imFriends.setId(IdGenerator.getId());
        imFriends.setSenderId(userId);
        imFriends.setReceiverId(friendsId);
        imFriends.setHealthStatus(HealthStatusEnum.NORMAL.getCode());
        imFriends.setCategory(CategoryEnum.FORMAL.getCode());
        imFriends.setCategoryChangeStatus(CategoryChangeStatusEnum.APPROVED_CHANGE.getCode());
        imFriends.setBurnAfterRead(BurnAfterReadEnum.NOT_ENABLED.getCode());
        imFriends.setBurnAfterReadDuration(0);
        imFriends.setChatRecordDelete(ChatRecordDeleteEnum.NOT_ENABLED.getCode());
        imFriends.setChatRecordConfidential(ChatRecordConfidentialEnum.NOT_ENABLED.getCode());
        imFriends.setScreenshotProhibited(ScreenshotProhibitedEnum.NOT_ENABLED.getCode());
        imFriends.setCreateTime(date);
        imFriends.setFriendAddTime(date);
        if (imSocialPrivacySettingFriends != null && imSocialPrivacySettingFriends.getFriendDeleteDuration() != null && imSocialPrivacySettingFriends.getFriendDeleteDuration() > 0) {
            imFriends.setDeleteTime(DateUtil.offsetDay(date, imSocialPrivacySettingFriends.getFriendDeleteDuration()));
        } else {
            // 默认6个月
            imFriends.setDeleteTime(DateUtil.offsetDay(date, 30 * 6));
        }
        imFriends.setFriendNote(resultMap.get(friendsId) == null ? null : resultMap.get(friendsId).getNickName());
        imFriends.setFriendNamePinyin(new HanyuPinyinUtil().toHanyuPinyin(imFriends.getFriendNote()));
        imFriendsList.add(imFriends);
        ImFriends friends = converter.convert(imFriends, ImFriends.class);
        friends.setId(IdGenerator.getId());
        friends.setSenderId(friendsId);
        friends.setReceiverId(userId);
        if (imSocialPrivacySettingVO != null && imSocialPrivacySettingVO.getFriendDeleteDuration() != null && imSocialPrivacySettingVO.getFriendDeleteDuration() > 0) {
            friends.setDeleteTime(DateUtil.offsetDay(date, imSocialPrivacySettingVO.getFriendDeleteDuration()));
        } else {
            // 默认6个月
            imFriends.setDeleteTime(DateUtil.offsetDay(date, 30 * 6));
        }
        friends.setFriendNote(resultMap.get(userId) == null ? null : resultMap.get(userId).getNickName());
        friends.setFriendNamePinyin(new HanyuPinyinUtil().toHanyuPinyin(friends.getFriendNote()));
        imFriendsList.add(friends);
        baseMapper.insertBatch(imFriendsList);
        // 清空缓存
        this.clearCache(friends.getSenderId() ,friends.getReceiverId());
    }

    /**
     * 根据对方id判断是否为好友
     *
     */
    private Boolean checkFriend(Long friendsId,Long userId) {
        return this.exists(new LambdaQueryWrapper<ImFriends>()
            .eq(ImFriends::getSenderId, friendsId).eq(ImFriends::getReceiverId, userId)
            .or()
            .eq(ImFriends::getSenderId, userId).eq(ImFriends::getReceiverId, friendsId)
        );
    }


    @Override
    public RemoteUserBasicVO selectFriendInfoOne(Long receiverId) {
        // 查询用户基本信息
        Long userId = LoginHelper.getUserId();
        RemoteUserBasicVO cacheUser = RedisUtils.getCacheObject(CacheConstants.TEMP_USER_BASIC_KEY + userId + receiverId);
        if (cacheUser != null) {
            return cacheUser;
        }
        RemoteUserBasicVO remoteUserBasicVO = remoteUserService.selectUserBasicById(receiverId);
        // 查询通讯录
        ImFriends imFriends = baseMapper.selectOne(new LambdaQueryWrapper<ImFriends>().eq(ImFriends::getSenderId, userId).eq(ImFriends::getReceiverId, receiverId));
        if (imFriends != null) {
            if (StringUtils.isNotEmpty(imFriends.getFriendNote())) {
                remoteUserBasicVO.setNickName(imFriends.getFriendNote());
            }
        }

        RedisUtils.setObjectIfAbsent(CacheConstants.TEMP_USER_BASIC_KEY + userId + receiverId, remoteUserBasicVO, Duration.ofHours(7));
        return remoteUserBasicVO;
    }

    @Override
    public ImFriendsSearchVO searchFriend(String code) {
        RemoteUserBasicVO userIdByTempQrcode = remoteUserService.getUserIdByTempQrcode(code);
        if (userIdByTempQrcode == null){
            throw new ServiceException("二维码失效");
        }
        ImFriendsSearchVO imFriendsSearchVO = new ImFriendsSearchVO();
        imFriendsSearchVO.setUserId(userIdByTempQrcode.getUserId());
        imFriendsSearchVO.setNickName(userIdByTempQrcode.getNickName());
        imFriendsSearchVO.setSignature(userIdByTempQrcode.getSignature());
        imFriendsSearchVO.setAvatar(userIdByTempQrcode.getAvatar());
        // 查询用户是否为好友，如果是好友需要查询备注信息
        LambdaQueryWrapper<ImFriends> lambdaQueryWrapper = new LambdaQueryWrapper<ImFriends>().select(ImFriends::getFriendNote).eq(ImFriends::getSenderId, LoginHelper.getUserId()).eq(ImFriends::getReceiverId, userIdByTempQrcode.getUserId());
        ImFriends imFriends = super.getOne(lambdaQueryWrapper);
        if (imFriends != null){
            imFriendsSearchVO.setNickName(imFriends.getFriendNote());
        }


        // 查询3条朋友圈
        List<ImSocialPostBasicVO> imSocialPostBasicList = imSocialPostService.selectImSocialPostListByUserId(userIdByTempQrcode.getUserId(), 3L);
        imFriendsSearchVO.setImSocialPostBasicList(imSocialPostBasicList);

        // 查询用户相册
        List<String> albumList = imSocialAlbumService.list(new Page<ImSocialAlbum>(1,9),new LambdaQueryWrapper<ImSocialAlbum>().eq(ImSocialAlbum::getUserId,userIdByTempQrcode.getUserId())).stream().map(ImSocialAlbum::getImageUrl).collect(Collectors.toList());
        imFriendsSearchVO.setAlbumList(albumList);
        return imFriendsSearchVO;
    }

    @Override
    public ImFriendsSearchVO tabMy() {
        Long userId = LoginHelper.getUserId();
        RemoteUserBasicVO userIdByTempQrcode = remoteUserService.selectUserBasicById(userId);
        ImFriendsSearchVO imFriendsSearchVO = new ImFriendsSearchVO();
        imFriendsSearchVO.setUserId(userIdByTempQrcode.getUserId());
        imFriendsSearchVO.setNickName(userIdByTempQrcode.getNickName());
        imFriendsSearchVO.setSignature(userIdByTempQrcode.getSignature());
        imFriendsSearchVO.setAvatar(userIdByTempQrcode.getAvatar());
        // 查询用户是否为好友，如果是好友需要查询备注信息
        LambdaQueryWrapper<ImFriends> lambdaQueryWrapper = new LambdaQueryWrapper<ImFriends>().select(ImFriends::getFriendNote).eq(ImFriends::getSenderId, LoginHelper.getUserId()).eq(ImFriends::getReceiverId, userIdByTempQrcode.getUserId());
        ImFriends imFriends = super.getOne(lambdaQueryWrapper);
        if (imFriends != null){
            imFriendsSearchVO.setNickName(imFriends.getFriendNote());
        }


        // 查询3条朋友圈
        List<ImSocialPostBasicVO> imSocialPostBasicList = imSocialPostService.selectImSocialPostListByUserId(userIdByTempQrcode.getUserId(), 3L);
        imFriendsSearchVO.setImSocialPostBasicList(imSocialPostBasicList);
        Long postTotal = imSocialPostService.postTotal(userId);
        imFriendsSearchVO.setPostTotal(postTotal);

        // 查询用户相册
        LambdaQueryWrapper<ImSocialAlbum> albumLambdaQueryWrapper = new LambdaQueryWrapper<ImSocialAlbum>().eq(ImSocialAlbum::getUserId, userIdByTempQrcode.getUserId());
        List<String> albumList = imSocialAlbumService.list(new Page<ImSocialAlbum>(1,9),albumLambdaQueryWrapper).stream().map(ImSocialAlbum::getImageUrl).collect(Collectors.toList());
        long albumTotal = imSocialAlbumService.count(albumLambdaQueryWrapper);

        imFriendsSearchVO.setAlbumList(albumList);
        imFriendsSearchVO.setAlbumTotal(albumTotal);
        return imFriendsSearchVO;
    }

    @Override
    public String generateCode() {
        return this.generateCode(0);
    }

    /**
     * 生成口令
     * @param number
     * @return
     */
    private String generateCode(int number) {
        number++;
        String generatePassword = RandomPasswordGenerator.generatePassword(60);
        // 如果生成5次都失败就不要生成了，避免死循环
        if (RedisUtils.hasKey(CacheConstants.TEMP_QRCODE_KEY+generatePassword)){
            if (number < 5){
                this.generateCode(number);
            }
            throw new ServiceException("生成失败");
        }
        RedisUtils.setCacheObject(CacheConstants.TEMP_QRCODE_KEY + SecureUtil.md5(generatePassword),remoteUserService.tempQrcode(),Duration.ofDays(2));
        return generatePassword;
    }

    @Override
    public String searchCode(String code) {
        if (StringUtils.isEmpty(code)){
            throw new ServiceException("口令不能为空");
        }
        // 查询口令对应的用户临时码，这里使用临时码是因为前端校验口令有效时跳转到的用户页面，需要根据临时码查询用户信息，这是避免不把用户id泄露。
        String tempQrcode = RedisUtils.getCacheObject(CacheConstants.TEMP_QRCODE_KEY + SecureUtil.md5(code));
        if (StringUtils.isEmpty(tempQrcode)){
            return null;
        }
        RemoteUserBasicVO userIdByTempQrcode = remoteUserService.getUserIdByTempQrcode(tempQrcode);
        if (userIdByTempQrcode == null){
            return null;
        }
        // 如果临时码是当前用户的，那么给空，因为当前用户的临时码对于自己来说没有必要。这个需求是为了用户自己复制了口令，下次打开APP是又检测到口令的情况。
        if (LoginHelper.getUserId().equals(userIdByTempQrcode.getUserId())){
            return null;
        }
        return tempQrcode;
    }

    /**
     * 清空缓存
     */
    public void clearCache(Long senderId,Long receiverId) {
        // 清空缓存,这里双向删除的原因是，禁止截屏这个字段是为对方设置的。例如：A设置了禁止截屏，那么B用户打开与A用户的聊天框时，需要查询A用户是否设置了禁止截屏
        RedisUtils.deleteObject(CacheConstants.CACHE_IM_FRIENDS_CHAT_KEY + receiverId + senderId);
        RedisUtils.deleteObject(CacheConstants.CACHE_IM_FRIENDS_CHAT_KEY + senderId + receiverId);
        RedisUtils.deleteObject(CacheConstants.TEMP_USER_BASIC_KEY + senderId + receiverId);
    }
}




